package io.github.yedaxia.apidocs.doc;

import java.awt.Color;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;

import io.github.yedaxia.apidocs.Utils;
import io.github.yedaxia.apidocs.parser.ControllerNode;
import io.github.yedaxia.apidocs.parser.ParamNode;
import io.github.yedaxia.apidocs.parser.RequestNode;

/**
 * build word api docs for a controller
 * @author wangya
 * @date 2018年12月27日
 */
public class WordControllerDocBuilder implements IControllerDocBuilder{
	
	private Document document;
	private BaseFont bfChinese;
	
    @Override
    public String buildDoc(ControllerNode controllerNode) throws IOException{
    	try {
	    	int count = 1;
	        for (RequestNode requestNode : controllerNode.getRequestNodes()) {
	            if (Utils.isNotEmpty(requestNode.getDescription())) {
	                addTitle(getParagraphThirdTitle(count + "、" + requestNode.getDescription(), getFontThirdTitle(), Element.ALIGN_LEFT));
	            }
	            
	            buildParamTable(controllerNode, requestNode);
	            
	            addTitle(getParagraphThirdTitle("参数列表 : ", getFontThirdTitle(), Element.ALIGN_LEFT));
	            if (requestNode.getParamNodes() != null) {
	                boolean isJsonBody = false;
	                for (ParamNode paramNode : requestNode.getParamNodes()) {
	                    if(paramNode.isJsonBody()) {
	                        addContent(paramNode.getDescription(), getFontNormal());
	                        isJsonBody = true;
	                        break;
	                    }
	                }
	                if(!isJsonBody) {
	                	buildParamTable(requestNode.getParamNodes());
	                }
	            }
	            addTitle(getParagraphThirdTitle("返回结果 : ", getFontThirdTitle(), Element.ALIGN_LEFT));
	            if (requestNode.getResponseNode() != null) {
	            	addContent(requestNode.getResponseNode().toJsonApi(), getFontNormal());
	            }
	            count ++;
	        }
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return "";
    }
    
    private void buildParamTable(ControllerNode controllerNode , RequestNode requestNode) throws DocumentException {
    	String methonStr = Arrays.toString(requestNode.getMethod().toArray());
        String url = "";
        if (Utils.isNotEmpty(requestNode.getUrl())) {
            url = controllerNode.getBaseUrl() + requestNode.getUrl();
        }
    	PdfPTable table = new PdfPTable(2);
    	/*
		 * 添加表头的元素，并设置表头背景的颜色
		 */
		Color chade = new Color(176, 196, 222);

		Paragraph para = new Paragraph("接口祥情", getFontThirdTitle());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
    	PdfPCell cell = new PdfPCell(para);
    	cell.setBackgroundColor(chade);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
    	table.addCell(cell);
    	
    	para = new Paragraph("", getFontThirdTitle());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
    	cell = new PdfPCell(para);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
    	cell.setBackgroundColor(chade);
		table.addCell(cell);

		para = new Paragraph("请求方式", getFontNormal());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
    	cell = new PdfPCell(para);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
    	table.addCell(cell);
    	
    	para = new Paragraph(methonStr.substring(1, methonStr.length() - 1), getFontNormal());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
    	cell = new PdfPCell(para);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

    	para = new Paragraph("请求地址", getFontNormal());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
    	cell = new PdfPCell(para);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
    	table.addCell(cell);

    	para = new Paragraph(url, getFontNormal());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
    	cell = new PdfPCell(para);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);
		
		this.document.add(table);
    }
    
    private void buildParamTable(List<ParamNode> paramNodes) throws DocumentException {
    	PdfPTable table = new PdfPTable(4);
    	/*
		 * 添加表头的元素，并设置表头背景的颜色
		 */
		Color chade = new Color(176, 196, 222);
		// 单元格
		Paragraph para = new Paragraph("参数名", getFontThirdTitle());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
		PdfPCell cell = new PdfPCell(para);
		cell.setBackgroundColor(chade);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		para = new Paragraph("类型", getFontThirdTitle());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
		cell = new PdfPCell(para);// 单元格
		cell.setBackgroundColor(chade);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		para = new Paragraph("必需", getFontThirdTitle());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
		cell = new PdfPCell(para);// 单元格
		cell.setBackgroundColor(chade);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		para = new Paragraph("描述", getFontThirdTitle());
		para.setAlignment(Element.ALIGN_CENTER);
		para.setSpacingBefore(5);
		para.setSpacingAfter(5);
		cell = new PdfPCell(para);// 单元格
		cell.setBackgroundColor(chade);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);
		
		for (ParamNode paramNode : paramNodes) {
			para = new Paragraph(paramNode.name, getFontNormal());
			para.setAlignment(Element.ALIGN_CENTER);
			para.setSpacingBefore(5);
			para.setSpacingAfter(5);
			cell = new PdfPCell(para);// 单元格
			cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
			cell.setHorizontalAlignment(Element.ALIGN_CENTER);
			table.addCell(cell);
			
			para = new Paragraph(paramNode.type, getFontNormal());
			para.setAlignment(Element.ALIGN_CENTER);
			para.setSpacingBefore(5);
			para.setSpacingAfter(5);
			cell = new PdfPCell(para);// 单元格
			cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
			cell.setHorizontalAlignment(Element.ALIGN_CENTER);
			table.addCell(cell);
			
			para = new Paragraph(String.valueOf(paramNode.required).equals("true") ? "是" : "否", getFontNormal());
			para.setAlignment(Element.ALIGN_CENTER);
			para.setSpacingBefore(5);
			para.setSpacingAfter(5);
			cell = new PdfPCell(para);// 单元格
			cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
			cell.setHorizontalAlignment(Element.ALIGN_CENTER);
			table.addCell(cell);
			
			para = new Paragraph(paramNode.description, getFontNormal());
			para.setAlignment(Element.ALIGN_CENTER);
			para.setSpacingBefore(5);
			para.setSpacingAfter(5);
			cell = new PdfPCell(para);// 单元格
			cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
			cell.setHorizontalAlignment(Element.ALIGN_CENTER);
			table.addCell(cell);
        }
		this.document.add(table);
    }
    
	/**
	 * 添加标题
	 * @param titleStr     标题
	 * @param font
	 * @param elementAlign 对齐方式
	 * @throws DocumentException
	 */
	public void addTitle(String titleStr, Font font, int elementAlign) throws DocumentException {
		Paragraph paragraph = new Paragraph(titleStr, font);
		// 设置标题格式对齐方式
		paragraph.setAlignment(elementAlign);
		//设置段落前后间距
		paragraph.setSpacingAfter(5);
		paragraph.setSpacingBefore(22);
		addTitle(paragraph);
	}
	
	/**
	 * 添加标题
	 * @param titleStr     标题
	 * @param font
	 * @param elementAlign 对齐方式
	 * @throws DocumentException
	 */
	private void addTitle(Paragraph paragraph) throws DocumentException {
		this.document.add(paragraph);
	}

	/**
	 * 添加内容
	 * @param content 内容体
	 * @param font
	 * @throws DocumentException
	 */
	private void addContent(String content, Font font) throws DocumentException {
		addContent(content, font, Element.ALIGN_LEFT);
	}
	
	/**
	 * 添加内容
	 * @param content
	 * @param font
	 * @param elementAlign
	 * @throws DocumentException
	 */
	private void addContent(String content, Font font, int elementAlign) throws DocumentException {
		Paragraph body = new Paragraph(content, font);
		// 设置标题格式对齐方式
		body.setAlignment(elementAlign);
		//设置缩进
		body.setIndentationLeft(40);  
		this.document.add(body);
	}
	
	/**
	 * @return the bfChinese
	 */
	public BaseFont getBfChinese() {
		return bfChinese;
	}

	/**
	 * @param bfChinese the bfChinese to set
	 */
	public void setBfChinese(BaseFont bfChinese) {
		this.bfChinese = bfChinese;
	}
	
	/**
	 * @return the title
	 */
	public Font getTitle() {
		return new Font(getBfChinese(), 20, Font.BOLD);
	}

	/**
	 * @return the fontThirdTitle
	 */
	public Font getFontThirdTitle() {
		return new Font(getBfChinese(), 14, Font.BOLD);
	}

	/**
	 * @return the fontSecondTitle
	 */
	public Font getFontSecondTitle() {
		return new Font(getBfChinese(), 16, Font.BOLD);
	}

	/**
	 * @return the fontNormal
	 */
	public Font getFontNormal() {
		return new Font(getBfChinese(), 12, Font.NORMAL);
	}

	/**
	 * @return the paragraphThirdTitle
	 */
	public Paragraph getParagraphThirdTitle(String content, Font font, int elementAlign) {
		Paragraph paragraph = new Paragraph(content, font);
		// 设置标题格式对齐方式
		paragraph.setAlignment(elementAlign);
		//设置段落前后间距
//		paragraph.setSpacingAfter(5);
		paragraph.setSpacingBefore(10);
		//设置缩进
		paragraph.setIndentationLeft(40);  
		return paragraph;
	}

    public void setDocument(Document document) {
    	this.document = document;
    }
}
